/*
 *    Copyright (c) 2018-2025, proj All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the proj developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: proj
 */

package com.ykht.proj.coupon.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ykht.proj.admin.api.entity.SysUser;
import com.ykht.proj.admin.api.feign.RemoteUserService;
import com.ykht.proj.common.core.util.R;
import com.ykht.proj.common.log.annotation.SysLog;
import com.ykht.proj.common.security.util.SecurityUtils;
import com.ykht.proj.coupon.Enum.MerchantTypeEnum;
import com.ykht.proj.coupon.Enum.UserTypeEnum;
import com.ykht.proj.coupon.entity.FxMerchantAccount;
import com.ykht.proj.coupon.entity.FxShopMoneyFlow;
import com.ykht.proj.coupon.service.CnUserExtService;
import com.ykht.proj.coupon.service.FxShopMoneyFlowService;
import com.ykht.proj.coupon.vo.BaseSearchTimeVo;
import com.ykht.proj.coupon.vo.FxShopMoneyFlowVo;
import com.ykht.proj.coupon.vo.FxWaiterExtVo;
import com.ykht.proj.coupon.vo.MoneyFlowVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;


/**
 * 门店资金流水
 *
 * @author proj code generator
 * @date 2021-02-01 19:00:17
 */
@RestController
@AllArgsConstructor
@RequestMapping("/fxshopmoneyflow")
@Api(value = "fxshopmoneyflow", tags = "门店资金流水管理")
@Slf4j
public class FxShopMoneyFlowController {

	private final FxShopMoneyFlowService fxShopMoneyFlowService;
	private final RemoteUserService remoteUserService;

	@ApiOperation(value = "分页查询", notes = "分页查询")
	@GetMapping("/page")
	public R getFxShopMoneyFlowPage(Page page, FxShopMoneyFlowVo fxShopMoneyFlowVo) {
		return fxShopMoneyFlowService.findPage(page, fxShopMoneyFlowVo);
	}

	@ApiOperation(value = "门店充值金额", notes = "门店充值金额")
	@GetMapping("/rechargeMoney")
//	@PreAuthorize("@pms.hasPermission('coupon_fxshopmoneyflow_view')" )
	public R rechargeMoney(FxShopMoneyFlow fxShopMoneyFlow) {
		BigDecimal money = fxShopMoneyFlowService.rechargeMoney(fxShopMoneyFlow.getShopId());
		return R.ok(money);
	}

	@ApiOperation(value = "门店账户", notes = "门店账户")
	@GetMapping("/shopPage")
//	@PreAuthorize("@pms.hasPermission('coupon_fxshopmoneyflow_view')" )
	public R getShopPage(Page page, FxShopMoneyFlowVo vo) {
		return fxShopMoneyFlowService.getShopPage(page, vo);
	}

	/**
	 * 新增门店资金流水
	 *
	 * @param list 门店资金流水
	 * @return R
	 */
	@ApiOperation(value = "新增门店资金流水", notes = "新增门店资金流水")
	@SysLog("新增门店资金流水")
	@PostMapping
	public R save(@RequestBody List<FxShopMoneyFlow> list) {
		String s = newOrderId();
		for (FxShopMoneyFlow fxShopMoneyFlow : list) {
			fxShopMoneyFlow.setCreateUser(SecurityUtils.getUserId());
			fxShopMoneyFlow.setCreateTime(LocalDateTime.now());
			fxShopMoneyFlow.setOrderId(s);
			fxShopMoneyFlow.setTradeId(newTradeId());
			BigDecimal balanceFast = fxShopMoneyFlowService.shopBalanceFast(fxShopMoneyFlow.getShopId(),null);
			if (fxShopMoneyFlow != null){
				fxShopMoneyFlow.setBalanceMoney(balanceFast.add(fxShopMoneyFlow.getFlowMoney()));
			}
			fxShopMoneyFlow.setFlowType(0);
		}
		return R.ok(fxShopMoneyFlowService.saveBatch(list));
	}

	public static String newOrderId() {
		StringBuffer orderNo = new StringBuffer("OR");
		orderNo.append(DateUtil.format(new Date(), "yyyyMMddHHmmsss"));
		Random random = new Random();
		double t = random.nextDouble();
		int d = (int) (t * 100000000);
		String str = d + "";
		int strLength = str.length();
		while (strLength < 8) {
			str = "0" + str;
			strLength++;
		}
		orderNo.append(str);
		return orderNo.toString();
	}


	public static String newTradeId() {
		StringBuffer orderNo = new StringBuffer("TR");
		orderNo.append(DateUtil.format(new Date(), "yyyyMMddHHmmsss"));
		Random random = new Random();
		double t = random.nextDouble();
		int d = (int) (t * 100000000);
		String str = d + "";
		int strLength = str.length();
		while (strLength < 8) {
			str = "0" + str;
			strLength++;
		}
		orderNo.append(str);
		return orderNo.toString();
	}


	/**
	 * 充值 b端账户表
	 * @param fxShopMoneyFlow 门店资金流水
	 * @return R
	 */
	@ApiOperation(value = "充值 b端账户表", notes = "充值 b端账户表")
	@SysLog("充值 b端账户表" )
	@PostMapping("addChargeMerchantAccount")
	public R addChargeMerchantAccount(@RequestBody FxShopMoneyFlow fxShopMoneyFlow) {
		log.info("->充值 b端账户表 :{}", fxShopMoneyFlow);
		fxShopMoneyFlow.setCreateUser(SecurityUtils.getUserId());
		fxShopMoneyFlow.setCreateTime(LocalDateTime.now());
		fxShopMoneyFlow.setTradeId(newTradeId());
		fxShopMoneyFlow.setFlowType(0);
		fxShopMoneyFlowService.addChargeMerchantAccount(fxShopMoneyFlow);
		return R.ok();
	}

	@ApiOperation(value = "分页查询 充值记录表", notes = "分页查询 充值记录表")
	@GetMapping("/getChargeRecordPage")
	public R<Page<MoneyFlowVo>> getChargeRecordPage(Page page, MoneyFlowVo moneyFlowVo) {
		log.info("->分页查询 充值记录表 :{}", page, moneyFlowVo);
		if (moneyFlowVo.getId() != null) {//平台端前端给的id
			FxMerchantAccount account = new FxMerchantAccount().selectById(moneyFlowVo.getId());
			moneyFlowVo.setMerchantType(account.getType());
			moneyFlowVo.setMerchantId(account.getTatId());
		}else {//品牌没给
			if (SecurityUtils.getUser().getUserType() == UserTypeEnum.brand.getValue()) {
				moneyFlowVo.setMerchantId(SecurityUtils.getSjId());
				moneyFlowVo.setMerchantType(MerchantTypeEnum.brand.getValue());
			}
		}
		page = fxShopMoneyFlowService.chargeRecordPage(page, moneyFlowVo);
		List<MoneyFlowVo> records = page.getRecords();
		if (records.size() > 0) {
			List<Long> ids = records.stream().filter(o->o.getCreateUser()!=null).map(itme -> itme.getCreateUser()).collect(Collectors.toList());
			List<SysUser> userList = remoteUserService.userByIds(ids);
			records.stream().forEach(itme -> {
				userList.stream().filter(o->o.getUserId().equals(itme.getCreateUser().intValue())).map(SysUser::getUsername).findAny().ifPresent(o->itme.setCreateUserName(o));
			});
			page.setRecords(records);
		}
		return R.ok(page);
	}

	@ApiOperation(value = "充值记录导出到excel")
	@GetMapping("/getChargeRecord4Excel")
	public void getChargeRecord4Excel(MoneyFlowVo moneyFlowVo) throws IOException {
		log.info("->充值记录导出到excel :{}", moneyFlowVo);
		if (moneyFlowVo.getId() != null) {//平台端前端给的id
			FxMerchantAccount account = new FxMerchantAccount().selectById(moneyFlowVo.getId());
			moneyFlowVo.setMerchantType(account.getType());
			moneyFlowVo.setMerchantId(account.getTatId());
		}else {//品牌没给
			if (SecurityUtils.getUser().getUserType() == UserTypeEnum.brand.getValue()) {
				moneyFlowVo.setMerchantId(SecurityUtils.getSjId());
				moneyFlowVo.setMerchantType(MerchantTypeEnum.brand.getValue());
			}
		}
		List<MoneyFlowVo> records = fxShopMoneyFlowService.chargeRecordPage(moneyFlowVo);
		if (records.size() > 0) {
			List<Long> ids = records.stream().filter(o->o.getCreateUser()!=null).map(itme -> itme.getCreateUser()).collect(Collectors.toList());
			List<SysUser> userList = remoteUserService.userByIds(ids);
			records.stream().forEach(itme -> {
				userList.stream().filter(o->o.getUserId().equals(itme.getCreateUser().intValue())).map(SysUser::getUsername).findAny().ifPresent(o->itme.setCreateUserName(o));
			});
		}

		HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
		ServletOutputStream out = response.getOutputStream();
		ExcelWriter writer = ExcelUtil.getWriter(true);

		//自定义标题别名
		writer.addHeaderAlias("createTime4String", "充值时间");
		writer.addHeaderAlias("orderId", "充值单号");
		writer.addHeaderAlias("tradeId", "交易流水号");
		writer.addHeaderAlias("name", "商家名称");
		writer.addHeaderAlias("merchantType4String", "商家类型");
		writer.addHeaderAlias("flowMoney", "充值金额");
		writer.addHeaderAlias("balanceMoney", "充值后余额");
		writer.addHeaderAlias("way", "充值方式");
		writer.addHeaderAlias("createUserName", "充值人");

		// 默认的，未添加alias的属性也会写出，如果想只写出加了别名的字段，可以调用此方法排除之
		writer.setOnlyAlias(true);
		writer.write(records, true);

		response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
		response.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode("充值记录", "ISO8859-1")+".xlsx");

		writer.flush(out, true);
		writer.close();
		IoUtil.close(out);
	}

}
